package br.com.pguide.activity;

import java.util.ArrayList;

import org.json.JSONException;

import br.com.pguide.R;
import br.com.pguide.estrutura.Estabelecimento;
import br.com.pguide.parser.Parser;
import br.com.pguide.utils.GeoUtils;
import br.com.pguide.utils.Mensagem;
import br.com.pguide.webservice.WebService;

import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TextView;

public class ListaDeEstabelecimentosActivity extends ListActivity {

	private ActivityList listAdapter;
	private ArrayList<Estabelecimento> lista;
	public static int position;
	public static RatingBar rb;
	String username, nome_estabelecimento;
	String[] estabelecimentos;
	LocationManager locationManager;
	public static double latitude, longitude;
	String provider;
	public static double EARTH_RADIUS_KM = 6367.43;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getListView().setBackgroundDrawable(getResources().getDrawable(R.drawable.common_background));

		getLocation();

		Intent it = getIntent();
		nome_estabelecimento = it.getStringExtra("nome_estabelecimento");
		username = it.getStringExtra("username");

		lista = Parser.get_estabelecimentos(WebService.get_estabelecimentos(username, nome_estabelecimento), this);

		estabelecimentos = new String[lista.size()];
		for (int i=0; i<lista.size(); i++) {
			estabelecimentos[i] = "";
		}

		atualizar(lista, estabelecimentos);
	}

	public void atualizar(ArrayList<Estabelecimento> itens, String[] estabelecimentos) {

		listAdapter = new ActivityList(ListaDeEstabelecimentosActivity.this, android.R.id.text1, itens, estabelecimentos);

		setListAdapter(listAdapter);
		ListView lv = getListView();
		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {

				Estabelecimento estab = lista.get(position);
				ListaDeEstabelecimentosActivity.position = position;

				Builder dialog = new Builder(ListaDeEstabelecimentosActivity.this);
				dialog.setTitle(estab.getNome_curto());
				dialog.setMessage(estab.getNome_completo() + "\n" +
						getString(R.string.cnpj) + ": " + estab.getCnpj() + "\n" +
						estab.getEndereco() + " - " + estab.getBairro() + "\n" +
						estab.getCidade() + "/" + estab.getEstado());
				dialog.setPositiveButton(R.string.avaliar, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						avaliar(ListaDeEstabelecimentosActivity.position);
					}
				});
				dialog.setNegativeButton(R.string.navegar, new OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						String uri = "http://maps.google.com/maps?saddr=" + latitude + "," + longitude + "&daddr=" + lista.get(ListaDeEstabelecimentosActivity.position).getLatitude()+","+lista.get(ListaDeEstabelecimentosActivity.position).getLongitude();
						Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri));
						intent.setClassName("com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
						startActivity(intent);
					}
				});
				dialog.show();
			}
		});
	}

	public void avaliar(int position) {
		Estabelecimento estab = lista.get(position);
		Builder dialog = new Builder(ListaDeEstabelecimentosActivity.this);
		dialog.setTitle(getString(R.string.avaliar) + " \"" + estab.getNome_curto() + "\"");
		dialog.setMessage(R.string.msg_avaliar);
		rb = new RatingBar(this);
		rb.setNumStars(5);
		dialog.setView(rb);
		dialog.setPositiveButton(R.string.salvar, new OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				try {
					if (WebService.avaliar_estabelecimento(username, lista.get(ListaDeEstabelecimentosActivity.position).getId(), rb.getRating())) {
						Mensagem.exibirToastCurto(getString(R.string.avaliacao_sucesso) +" "+ String.valueOf(rb.getRating()), ListaDeEstabelecimentosActivity.this);
					} else {
						Mensagem.exibirToastCurto(getString(R.string.avaliacao_falha), ListaDeEstabelecimentosActivity.this);
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		});
		dialog.setNegativeButton(R.string.cancelar, null);
		dialog.show();
	}

	public void getLocation() {
		if (android.os.Build.DEVICE.equals("sdk") || android.os.Build.DEVICE.equals("generic")) {
			// modo de desenvolvimento - sdk
			latitude = -9.4157852;
			longitude = -36.6223826;
			return;
		}

		habilitarGPS();
		// Get the location manager
		LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		// Define the criteria how to select the locatioin provider -> use
		// default
		Criteria criteria = new Criteria();
		String provider = locationManager.getBestProvider(criteria, false);
		Location location = locationManager.getLastKnownLocation(provider);
		if (location != null) {
			latitude = (double) (location.getLatitude());
			longitude = (double) (location.getLongitude());
		} else {
			Mensagem.exibirMensagem("Latitude is not available" + 
					"\nLongitude is not available", this);
		}
	}

	public void habilitarGPS() {
		// a classe LocationManager provê o acesso ao serviço de localização do Android
		LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
		boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);

		if (!enabled) {
			/* o GPS não pode ser habilitado diretamente em código
			 ** o usuário precisa autorizar a sua habilitção 
			 ** apenas a Activity do Google Map habilita automaticamente o GPS */
			Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
			startActivity(intent);
		}
	}

	public void refreshLocation(int position){
		try {
			Estabelecimento estabelecimento = lista.get(position);
			double distancia = GeoUtils.geoDistanceInKm(latitude, longitude,
					estabelecimento.getLatitude(), estabelecimento.getLongitude()); 
			estabelecimento.setDistancia(distancia);
		} catch (Exception e) {
			Mensagem.exibirMensagem(e.getMessage().toString(), this);
		}

	}

	public void onLocationChanged(Location location) {
		latitude = location.getLatitude();
		longitude = location.getLongitude();
	}

	class ActivityList extends ArrayAdapter<String> {

		ArrayList<Estabelecimento> estabs = null;

		public ActivityList(Context context, int textViewResourceId, ArrayList<Estabelecimento> itens, String[] estabelecimentos) {
			super(context, textViewResourceId, estabelecimentos);
			this.estabs = itens;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if(convertView == null){
				LayoutInflater inflater = LayoutInflater.from(ListaDeEstabelecimentosActivity.this);
				convertView = inflater.inflate(R.layout.lista_estabelecimentos, parent, false);
				holder = new ViewHolder();

				holder.estabelecimento = (TextView) convertView.findViewById(R.id._estabelecimento);
				holder.endereco = (TextView) convertView.findViewById(R.id._endereco);
				holder.cidade = (TextView) convertView.findViewById(R.id._cidade);
				holder.estado = (TextView) convertView.findViewById(R.id._estado);
				holder.distancia = (TextView) convertView.findViewById(R.id._distancia);
				holder.reputacao_media = (TextView) convertView.findViewById(R.id._reputacao);

				convertView.setTag(holder);
			} else{
				holder = (ViewHolder) convertView.getTag();
			}
			holder.estabelecimento.setText(estabs.get(position).getNome_curto());
			holder.endereco.setText(estabs.get(position).getEndereco());
			holder.cidade.setText(estabs.get(position).getCidade());
			holder.estado.setText("/"+estabs.get(position).getEstado());

			refreshLocation(position);
			holder.distancia.setText(getString(R.string.distancia) + String.format(": %.1f km", lista.get(position).getDistancia()));

			String query = WebService.get_reputacao(estabs.get(position).getReputacaoID());
			int qtd_avaliacoes = Parser.getReputacao_QuantidadeDeAvaliacoes(query, ListaDeEstabelecimentosActivity.this);
			double media = Parser.getReputacao_Media(query, ListaDeEstabelecimentosActivity.this)*2;

			if (qtd_avaliacoes==0){
				holder.reputacao_media.setText(getString(R.string.local_nao_avaliado));
			} else {
				holder.reputacao_media.setText(getString(R.string.reputacao) + String.format(": %.2f", media) + "  (" + qtd_avaliacoes + " " + getString(R.string.avaliacoes) + ") ");
			}


			return convertView;
		}
	}

	static class ViewHolder{
		TextView estabelecimento;
		TextView endereco;
		TextView cidade;
		TextView estado;
		TextView distancia;
		TextView reputacao_media;
	}
}
